/**
 * ʒ[Ŕ˂e𔭎˂
 * x傫Aˈʒǔ덷傫Ȃ
 * 
 * @param {Integer} x         exW
 * @param {Integer} y         eyW
 * @param {Integer} speed     x
 * @param {Integer} angle     px
 * @param {Integer} graph     摜
 * @param {Integer} delay     xt[
 * @param {Array}   refflag   EEEEŔ˂邩( zœB1Ŕ )
 * @param {Integer} refnumber ˉ
 */
task ReflectShot( x, y, speed, angle, graph, delay, refflag, refnumber ){
	let refnum = refnumber;
	
	let obj = Obj_Create( OBJ_SHOT );
	Obj_SetPosition( obj, x, y );
	Obj_SetSpeed( obj, speed );
	Obj_SetAngle( obj, angle );
	ObjShot_SetGraphic( obj, graph );
	ObjShot_SetDelay( obj, delay );
	
	while( !Obj_BeDeleted( obj ) ){
		if( ( Obj_GetX( obj ) <= GetClipMinX() && refflag[ 0 ] == 1 && refnum > 0 ) || ( Obj_GetX( obj ) >= GetClipMaxX() && refflag[ 2 ] == 1 && refnum > 0 ) ){
			if( refnum > 1 ){
				Obj_SetAngle( obj, 180 - Obj_GetAngle( obj ) );
				refnum -= 1;
			}else{
				CreateShot01( Obj_GetX( obj ), Obj_GetY( obj ), speed, 180 - Obj_GetAngle( obj ), graph, 0 );
				Obj_Delete( obj );
			}
		}
		
		if( ( Obj_GetY( obj ) <= GetClipMinY() && refflag[ 1 ] == 1 && refnum > 0 ) || ( Obj_GetY( obj ) >= GetClipMaxY() && refflag[ 3 ] == 1 && refnum > 0 ) ){
			if( refnum > 1 ){
				Obj_SetAngle( obj, -Obj_GetAngle( obj ) );
				refnum -= 1;
			}else{
				CreateShot01( Obj_GetX( obj ), Obj_GetY( obj ), speed, -Obj_GetAngle( obj ), graph, 0 );
				Obj_Delete( obj );
			}
		}
		
		yield;
	}
}

/**
 * ʒ[Ŕ˂郌[U[𔭎˂
 * x傫Aˈʒǔ덷傫Ȃ
 * 
 * @param {Integer} x         exW
 * @param {Integer} y         eyW
 * @param {Integer} speed     x
 * @param {Integer} angle     px
 * @param {Integer} lng       [U[̒
 * @param {Integer} wid       [U[̕
 * @param {Integer} graph     摜
 * @param {Integer} delay     xt[
 * @param {Array}   refflag   EEEEŔ˂邩( zœB1Ŕ )
 * @param {Integer} refnumber ˉ
 */
task RefrectLaser( x, y, speed, angle, lng, wid, graph, delay, refflag, refnumber ){
	let refnum = refnumber;
	
	let vLng = 0;
	
	let mx = speed * cos( angle );
	let my = speed * sin( angle );
	
	let vx = x;
	let vy = y;
	
	let obj = Obj_Create( OBJ_LASER );
	Obj_SetPosition( obj, x, y );
	Obj_SetSpeed( obj, speed );
	Obj_SetAngle( obj, angle );
	ObjShot_SetGraphic( obj, graph );
	ObjShot_SetDelay( obj, delay );
	
	ObjLaser_SetLength( obj, 0 );
	ObjLaser_SetWidth( obj, wid );
	ObjLaser_SetSource( obj, false );
	
	while( !Obj_BeDeleted( obj ) ){
		if( vLng < lng ){
			vLng += speed;
			ObjLaser_SetLength( obj, vLng );
		}else{
			vLng = lng;
			vx += mx;
			vy += my;
		}
		
		Obj_SetPosition( obj, vx, vy );
		
		if( ( ObjLaser_GetEndX( obj ) <= GetClipMinX() && refflag[ 0 ] == 1 && refnum > 0 ) || ( ObjLaser_GetEndX( obj ) >= GetClipMaxX() && refflag[ 2 ] == 1 && refnum > 0 ) ){
			RefrectLaser( ObjLaser_GetEndX( obj ), ObjLaser_GetEndY( obj ), speed, 180 - angle, lng, wid, graph, 0, refflag, refnumber - 1 );
			refnum = 0;
		}
		
		if( ( ObjLaser_GetEndY( obj ) <= GetClipMinY() && refflag[ 1 ] == 1 && refnum > 0 ) || ( ObjLaser_GetEndY( obj ) >= GetClipMaxY() && refflag[ 3 ] == 1 && refnum > 0 ) ){
			RefrectLaser( ObjLaser_GetEndX( obj ), ObjLaser_GetEndY( obj ), speed,      -angle, lng, wid, graph, 0, refflag, refnumber - 1 );
			refnum = 0;
		}
		
		yield;
	}
}

/**
 * d͂ŉe𔭎˂
 * pxAd͊px͐Ίpxw( SetShotDirectionTypȅԂɂ͊֌WȂ )
 * 
 * @param {Integer} x        exW
 * @param {Integer} y        eyW
 * @param {Integer} speed    x
 * @param {Integer} angle    px
 * @param {Integer} graph    摜
 * @param {Integer} delay    xt[
 * @param {Integer} grvspeed d͉x
 * @param {Integer} grvangle d͊px
 * @param {Integer} maxspeed ő呬x
 */
function GravityShot( x, y, speed, angle, graph, delay, grvspeed, grvangle, maxspeed ){
	let xSpeed = speed * cos( angle );
	let ySpeed = speed * sin( angle );
	let accXSpeed = grvspeed * cos( grvangle );
	let accYSpeed = grvspeed * sin( grvangle );
	let maxXSpeed = [ maxspeed, -maxspeed ][ accXSpeed < 0 ];
	let maxYSpeed = [ maxspeed, -maxspeed ][ accYSpeed < 0 ];
	
	CreateShot12( x, y, xSpeed, ySpeed, accXSpeed, accYSpeed, maxXSpeed, maxYSpeed, graph, delay );
}

/**
 * d͂ŉe𔭎˂֐Obj
 * pxAd͊px͐Ίpxw( SetShotDirectionTypȅԂɂ͊֌WȂ )
 * 
 * @param {Integer} x        exW
 * @param {Integer} y        eyW
 * @param {Integer} speed    x
 * @param {Integer} angle    px
 * @param {Integer} graph    摜
 * @param {Integer} delay    xt[
 * @param {Integer} grvspeed d͉x
 * @param {Integer} grvangle d͊px
 * @param {Integer} maxspeed ő呬x
 * @return {Object} 쐬IuWFNgid
 */
function GravityShotObj( x, y, speed, angle, graph, delay, gspeed, gangle, maxspeed ){
	let obj = Obj_Create( OBJ_SHOT );
	Obj_SetPosition( obj, x, y );
	Obj_SetSpeed( obj, speed );
	Obj_SetAngle( obj, angle );
	ObjShot_SetGraphic( obj, graph );
	ObjShot_SetDelay( obj, delay );
	
	ObjShot_SetGravity( obj, speed, angle, delay, gspeed, gangle, maxspeed );
	
	return obj;
}

/**
 * Ώۂ̃IuWFNgeɏd͉
 * 
 * @param {Object}  obj      Ώۂ̃IuWFNge
 * @param {Integer} speed    x
 * @param {Integer} angle    px
 * @param {Integer} delay    xt[
 * @param {Integer} grvspeed d͉x
 * @param {Integer} grvangle d͊px
 * @param {Integer} maxspeed ő呬x
 */
task ObjShot_SetGravity( obj, speed, angle, delay, gspeed, gangle, maxspeed ){
	let ox = speed * cos( angle );
	let oy = speed * sin( angle );
	let vx = gspeed * cos( gangle );
	let vy = gspeed * sin( gangle );
	
	loop( delay ){
		yield;
	}
	
	while( !Obj_BeDeleted( obj ) ){
		ox += vx;
		oy += vy;
		
		speed = ( ox ^ 2 + oy ^ 2 ) ^ 0.5;
		
		if( speed > maxspeed ){
			speed = maxspeed;
		}
		
		angle = atan2( oy, ox );
		
		Obj_SetSpeed( obj, speed );
		Obj_SetAngle( obj, angle );
		
		yield;
	}
}
